layui.define(
  ["plus", "plusConfig", "plusRouter", "plusUtil", "plusTools"],
  function (exports) {
    "use strict";

    var $ = layui.jquery,
      layer = layui.layer,
      element = layui.element,
      plus = layui.plus,
      config = layui.plusConfig,
      plusRouter = layui.plusRouter,
      plusUtil = layui.plusUtil,
      plusTools = layui.plusTools;

    var layoutDom = ".plus-admin-layout";
    var headerDom = layoutDom + ">.plus-admin-header";
    var topMenuDom = headerDom + ">.header-top";
    var menuDom = layoutDom + ">.plus-admin-menu";
    var subMenuDom = layoutDom + ">.plus-admin-submenu";
    var bodyDom = layoutDom + ">.plus-admin-body";
    var tabDom = ".plus-admin-body>.layui-tab";
    var body_HeaderDom = bodyDom + ">.plus-admin-body-header";
    var tabFilter = "plus-admin-pagetabs";
    var navFilter = "plus-admin-submenu-nav";
    var isAdd = false;
    var menu = {
      init: function () {
        menu.pushTab();
        menu.pushRight();

        $(".plus-admin-menu-items").on("click", "a", function (e) {
          var href = $(this).attr("href");
          var option = {
            id: $(this).attr("plus-id"),
            haschild: $(this).attr("haschild"),
            name: $(this).attr("plus-title"),
          };
          menu.activeMenu(href, option);
          if (
            href.indexOf("#") !== 0 ||
            $(tabDom).attr("router-autoRefresh") != "true"
          ) {
            return;
          }
          if (!isAdd) plus.refresh(href.substring(1), true);
        });

        $(topMenuDom).on("click", "a", function (e) {
          var href = $(this).attr("href");
          var option = {
            id: $(this).attr("plus-id"),
            haschild: $(this).attr("haschild"),
            name: $(this).attr("plus-title"),
          };
          menu.activeMenu(href, option);
          if (
            href.indexOf("#") !== 0 ||
            $(tabDom).attr("router-autoRefresh") != "true"
          ) {
            return;
          }
          if (!isAdd) plus.refresh(href.substring(1), true);
        });

        // element.on("nav(" + navFilter + ")", function (elem) {
        //   var href = $(elem).attr("href");
        //   var haschild = $(elem).attr("haschild");
        //   var parentId = $(elem).attr("plus-parentid");
        //   if (
        //     href.indexOf("#") !== 0 ||
        //     $(tabDom).attr("lay-autoRefresh") != "true"
        //   ) {
        //     var url = $(
        //       tabDom +
        //         '>.layui-tab-content>.layui-tab-item>div[lay-id="' +
        //         href.replace('#','') +
        //         '"]'
        //     ).attr("lay-url");
        //     console.log(url);
        //     return;
        //   }
        //   if (!isAdd) plus.refresh(href.substring(1), true);
        // });

        element.on("tab(" + tabFilter + ")", function () {
          var hash = $(this).attr("lay-id");
          var tabThisDom = $(
            tabDom +
              '>.layui-tab-content>.layui-tab-item>div[lay-id="' +
              hash +
              '"]'
          );
          var url = tabThisDom.attr("lay-url");
          var id = tabThisDom.attr("plus-id");
          var parentId = tabThisDom.attr("plus-parentid");
          var option = {
            id: Number(parentId) === 0 ? id : parentId,
            haschild: tabThisDom.attr("haschild"),
            name: tabThisDom.attr("plus-title"),
          };
          menu.activeMenu(url, option);
          menu.activeSubMenu(url);
          plus.rollPage("auto");
          if ($(tabDom).attr("router-autoRefresh") == "true" && !isAdd)
            plus.refresh(url, true);
          else plusRouter.go(url);
          isAdd = false;
          layui.event.call(this, "plus", "show(" + hash + ")");
          layui.event.call(this, "plus", "tab({*})", { layId: hash });
          plus.resizeTableHeight();
        });

        element.on("tabDelete(" + tabFilter + ")", function (data) {
          if (data.index > 0 && data.index <= menu.plusTabLists.length) {
            var hashPath = menu.getHashPath(
              menu.plusTabLists[data.index - 1].href
            );
            layui.event.call(this, "plus", "destroy(" + hashPath + ")");
            menu.plusTabLists.splice(data.index - 1, 1);
            if (config.cacheTab)
              plus.putTempData("menuTabs", menu.plusTabLists);
            layui.event.call(this, "plus", "tabDelete({*})", {
              layId: hashPath,
            });
          }
          if ($(tabDom + ">.layui-tab-title>li.layui-this").length === 0)
            $(tabDom + ">.layui-tab-title>li:last").trigger("click");
        });
      },
      plusTabLists: [],
      reg: function (menus, format) {
        $.each(menus, function (i, data) {
          if (format) data = format(data);
          if (data.url && data.url.indexOf("#") === 0) {
            plusRouter.reg(data.url, function (info) {
              var option = {
                info: $.extend(info, {
                  id: data.id,
                  name: data.name,
                  url: data.url,
                  iframe: data.iframe,
                  icon: data.icon,
                  parentId: data.parentId,
                  parentIds: data.parentIds,
                }),
                data: data,
              };
              menu.changeView(option);
            });
          }
          if (data.subMenus) {
            menu.reg(data.subMenus, format);
          }
        });
      },
      removeHide: function (menus, format) {
        for (var i = menus.length - 1; i >= 0; i--) {
          if (format) menus[i] = format(menus[i]);
          if (menus[i].subMenus) menu.removeHide(menus[i].subMenus);
          if (menus[i].show === false) {
            menus.splice(i, 1);
          } else {
            if (!menus[i].target) menus[i].target = "_self";
            if (!menus[i].url) menus[i].url = "javascript:;";
          }
        }
      },
      renderMenu: function (data, tpl, callback, tplOpen, tplClose, format) {
        if (typeof tpl === "function") {
          tplClose = tplOpen;
          tplOpen = callback;
          callback = tpl;
          tpl = undefined;
        }
        menu.removeHide(data, format);
        var elem = config.topMenu ? "#topMenuNav" : "#menuNav";
        var navElem = config.topMenu
          ? topMenuDom
          : menuDom + ">.plus-admin-menu-items";
        var html = plusUtil.tpl(
          tpl || $(elem).html() || "",
          data,
          tplOpen || config.tplOpen,
          tplClose || config.tplClose
        );
        $(navElem).html(html);
        var html = plusUtil.tpl(
          tpl || $("#menuNav").html() || "",
          data,
          tplOpen || config.tplOpen,
          tplClose || config.tplClose
        );
        $(menuDom + ">.plus-admin-menu-items").html(html);
      },
      renderSubMenu: function (
        info,
        data,
        tpl,
        callback,
        tplOpen,
        tplClose,
        format
      ) {
        menu.removeHide(data, format);
        var obj = {
          info: info,
          data: data,
        };
        var html = plusUtil.tpl(
          tpl || $("#subMenuNav").html() || "",
          obj,
          tplOpen || config.tplOpen,
          tplClose || config.tplClose
        );
        $(subMenuDom + ">.layui-nav").html(html);
        element.render("nav", "plus-admin-submenu-nav");
        // menu.activeSubMenu(data[0].url);
        // $(subMenuDom + " .layui-nav li.layui-this a")[0].click();
      },
      activeMenu: function (url, op) {
        if (!url) url = location.hash;
        if (!op) op = plusTools.searchMenus(url, "mine");
        var id = op.id,
          haschild = op.haschild,
          title = op.name;
        if (haschild === "1") {
          $(".plus-admin-submenu").show();
          var menuLeft = config.topMenu ? 110 : 160;
          $(".plus-admin-body").css("left", menuLeft + "px");
        } else {
          $(".plus-admin-submenu").hide();
          let menuLeft = config.topMenu ? 0 : 50;
          $(".plus-admin-body").css("left", menuLeft + "px");
        }
        var aDom;
        if (config.topMenu) {
          $(topMenuDom + ">.menu-item").removeClass("active");
          aDom = $(topMenuDom + '>.menu-item a[plus-id="' + id + '"]');
        } else {
          $(menuDom + ">.plus-admin-menu-items .active").removeClass("active");
          aDom = $(
            menuDom +
              '>.plus-admin-menu-items>.menu-item a[plus-id="' +
              id +
              '"]'
          );
        }
        if (aDom.length > 0) {
          aDom.parent().addClass("active");
        }
        var subMenus = plusTools.searchMenus(id);
        if (subMenus !== undefined && subMenus.length > 0) {
          menu.renderSubMenu(
            { name: title, id: id, haschild: haschild },
            subMenus
          );
        }
        plus.foldMenu();
      },
      activeSubMenu: function (url, anim) {
        if (anim === undefined) anim = true;
        if (!url) url = location.hash;
        if (url.indexOf("#") === 0) {
          url = url.replace("#", "");
        }
        $(
          subMenuDom +
            ">.layui-nav .layui-nav-item .layui-nav-child dd.layui-this"
        ).removeClass("layui-this");
        $(subMenuDom + ">.layui-nav .layui-nav-item.layui-this").removeClass(
          "layui-this"
        );
        var $a = $(subMenuDom + '>.layui-nav a[href="#' + url + '"]');
        if ($(subMenuDom + ">.layui-nav").attr("lay-shrink") === "_all") {
          var $pChilds = $a.parent("dd").parents(".layui-nav-child");
          $(subMenuDom + ">.layui-nav .layui-nav-itemed>.layui-nav-child")
            .not($pChilds)
            .css("display", "block")
            .slideUp(anim ? "fast" : 0, function () {
              $(this).css("display", "");
            });
          $(subMenuDom + ">.layui-nav .layui-nav-itemed")
            .not($pChilds.parent())
            .removeClass("layui-nav-itemed");
        }
        $a.parent().addClass("layui-this");
        var $asParents = $a.parent("dd").parents(".layui-nav-child").parent();
        var $childs = $asParents
          .not(".layui-nav-itemed")
          .children(".layui-nav-child");
        $childs.slideDown(anim ? "fast" : 0, function () {
          if ($(this).is($childs.last())) {
            $childs.css("display", "");
            var topBeyond =
              $a.offset().top + $a.outerHeight() + 30 - plus.getPageHeight();
            var topDisparity = 50 + 65 - $a.offset().top;
            if (topBeyond > 0) {
              $(subMenuDom).animate(
                { scrollTop: $(subMenuDom).scrollTop() + topBeyond },
                anim ? 300 : 0
              );
            } else if (topDisparity > 0) {
              $(subMenuDom).animate(
                { scrollTop: $(subMenuDom).scrollTop() - topDisparity },
                anim ? 300 : 0
              );
            }
          }
        });
        $asParents.addClass("layui-nav-itemed");
      },
      changeView: function (op) {
        var info = op.info,
          first = op.first,
          data = op.data;
        var haschild =
          data.parentId === 0
            ? data.subMenus !== undefined
              ? "1"
              : "0"
            : data.parentIds.split(",").length > 1
            ? "1"
            : "0";
        var name =
          data.parentId === 0
            ? plusTools.searchMenus(data.id, "mine").name
            : plusTools.searchMenus(data.parentIds.split(",")[1], "mine").name;
        var path = menu.getHashPath(info);
        var contentDom = bodyDom + ">div[lay-id]";
        if (config.pageTabs) {
          var flag;
          $(tabDom + ">.layui-tab-title>li").each(function () {
            if ($(this).attr("lay-id") === path) flag = true;
          });
          if (!flag) {
            if (menu.plusTabLists.length + 1 >= config.maxTabNum) {
              layer.msg(
                "只能打开" + config.maxTabNum + "个页签，请关闭一些吧！"
              );
              return history.back();
            }
            isAdd = true;
            var tabHtml = [
              '<div lay-id="',
              path,
              '" lay-url="',
              info.href,
              '" plus-id="',
              data.id,
              '" plus-parentid="',
              data.parentIds !== undefined ? data.parentIds.split(",")[1] : 0,
              '" haschild="',
              haschild,
              '" plus-title="',
              name,
              '"></div>',
            ].join("");
            element.tabAdd(tabFilter, {
              id: path,
              title:
                '<span class="title">' +
                (info.icon || "") +
                (info.name || "") +
                "</span>",
              content: tabHtml,
            });
            if (path !== plusRouter.index) menu.plusTabLists.push(info);
            if (config.cacheTab)
              plus.putTempData("menuTabs", menu.plusTabLists);
          }
          contentDom =
            tabDom +
            '>.layui-tab-content>.layui-tab-item>div[lay-id="' +
            path +
            '"]';
          var oldUrl = $(contentDom).attr("lay-url");
          if (info.href !== oldUrl) {
            layui.event.call(this, "plus", "destroy(" + path + ")");
            $(contentDom).attr("lay-url", info.href);
            flag = false;
            for (var i = 0; i < menu.plusTabLists.length; i++)
              if (menu.plusTabLists[i].href === oldUrl)
                menu.plusTabLists[i] = info;
            if (config.cacheTab)
              plus.putTempData("menuTabs", menu.plusTabLists);
          }
          if (!flag || info.refresh) {
            if (info.refresh)
              layui.event.call(this, "plus", "destroy(" + path + ")");
            menu.renderView(info, contentDom);
          }
          if (!info.noChange && !info.refresh)
            element.tabChange(tabFilter, path);
        } else {
          if ($(contentDom).length === 0) {
            if (config.showTabs) {
              $(bodyDom).html(
                [
                  '<div class="plus-admin-body-header">',
                  '   <span class="plus-admin-body-header-title"></span>',
                  '   <span class="layui-breadcrumb pull-right" lay-filter="plus-admin-body-header-breadcrumb" style="visibility: visible;"></span>',
                  "</div>",
                  '<div class="plus-admin-body-content" lay-id="',
                  path,
                  '" lay-url="',
                  info.href,
                  '" plus-id="',
                  data.id,
                  '" plus-parentid="',
                  data.parentIds !== undefined
                    ? data.parentIds.split(",")[1]
                    : 0,
                  '" haschild="',
                  haschild,
                  '" plus-title="',
                  name,
                  '"></div>',
                ].join("")
              );
              $('[lay-filter="plus-admin-body-header-breadcrumb"]').html(
                menu.getBreadcrumbHtml(path)
              );
            } else {
              $(bodyDom).html(
                [
                  '<div class="plus-admin-body-content" lay-id="' +
                    path +
                    '" lay-url="',
                  info.href,
                  '" plus-id="',
                  data.id,
                  '" plus-parentid="',
                  data.parentIds !== undefined
                    ? data.parentIds.split(",")[1]
                    : 0,
                  '" haschild="',
                  data.parentId === 0
                    ? data.subMenus !== undefined
                      ? 1
                      : 0
                    : data.parentIds.split(",").length > 1
                    ? 1
                    : 0,
                  '" plus-title="',
                  data.parentId === 0
                    ? plusTools.searchMenus(data.id, "mine").name
                    : plusTools.searchMenus(
                        data.parentIds.split(",")[1],
                        "mine"
                      ).name,
                  '"></div>',
                ].join("")
              );
            }
          } else {
            layui.event.call(
              this,
              "plus",
              "destroy(" + $(contentDom).attr("lay-id") + ")"
            );
            $(contentDom).attr("lay-id", path).attr("lay-url", info.href);
          }
          menu.plusTabLists.splice(0, menu.plusTabLists.length);
          if (config.showTabs) {
            if (path === plusRouter.index) {
              menu.setTabTitle(
                $(info.name).text() ||
                  $(menuDom + ' [href="#/' + plusRouter.index + '"]').text() ||
                  "🖥️"
              );
            } else {
              menu.plusTabLists.push(info);
              menu.setTabTitle(info.name);
            }
            $(bodyDom + ">.plus-admin-body-content").css("top", "42px");
          } else {
            if (!(path === plusRouter.index)) {
              menu.plusTabLists.push(info);
            }
          }
          menu.renderView(info, contentDom);
          if (config.cacheTab) plus.putTempData("menuTabs", menu.plusTabLists);
        }
        var option = {
          id: data.parentId,
          haschild: haschild,
          name: name,
        };
        menu.activeMenu(info.href, option);
        if (haschild == "1") {
          menu.activeSubMenu(info.href);
        }
        plusTools.foldMenu();
      },
      renderView: function (info, contentDom, loadingDom) {
        var $contentDom = $(contentDom);
        if (!loadingDom) loadingDom = $contentDom.parent();
        if (!info.iframe) {
          plus.showLoading({ elem: loadingDom, size: "" });
          plus.request({
            url: "views/" + info.path.join("/") + ".html",
            data: info.search,
            dataType: "html",
            success: function (res) {
              plus.hideLoading({ elem: loadingDom });
              if (typeof res !== "string") res = JSON.stringify(res);
              if (res.indexOf("<tpl") === 0) {
                var $html = $("<div>" + res + "</div>"),
                  tplAll = {};
                $html.find("script,[tpl-ignore]").each(function (i) {
                  var $this = $(this);
                  tplAll["temp_" + i] = $this[0].outerHTML;
                  $this.after("${temp_" + i + "}").remove();
                });
                res = plusUtil.tpl(
                  $html.html(),
                  info,
                  config.tplOpen,
                  config.tplClose
                );
                for (var f in tplAll)
                  res = res.replace("${" + f + "}", tplAll[f]);
              }
              $contentDom.html(res);
              // plus.renderPerm();
              plus.renderTpl(contentDom + " [plus-admin-tpl]");
            },
          });
        } else {
          $contentDom.html(
            [
              '<div class="plus-admin-iframe" style="-webkit-overflow-scrolling: touch;">',
              '   <iframe src="',
              info.iframe,
              '" class="plus-admin-iframe" frameborder="0"></iframe>',
              "</div>",
            ].join("")
          );
        }
      },
      getHashPath: function (hash) {
        if (!hash || typeof hash === "string")
          hash = plusRouter.routerInfo(hash);
        return hash.path.join("/");
      },
      go: function (hash) {
        plusRouter.go(hash);
      },
      clearTabCache: function () {
        plus.putTempData("menuTabs", null);
      },
      setTabTitle: function (title, hash) {
        if (config.pageTabs) {
          if (!hash) hash = menu.getHashPath();
          if (hash)
            $(
              tabDom + '>.layui-tab-title>li[lay-id="' + hash + '"] .title'
            ).html(title || "");
        } else if (title) {
          $(body_HeaderDom + ">.plus-admin-body-header-title").html(title);
          $(body_HeaderDom).addClass("show");
          $(menuDom).css("box-shadow", "0 1px 0 0 rgba(0, 0, 0, .03)");
        } else {
          $(body_HeaderDom).removeClass("show");
          $(menuDom).css("box-shadow", "");
        }
      },
      setTabTitleHtml: function (html) {
        if (config.pageTabs) return;
        if (!html) return $(body_HeaderDom).removeClass("show");
        $(body_HeaderDom).html(html);
        $(body_HeaderDom).addClass("show");
      },
      getBreadcrumb: function (hash) {
        if (!hash) hash = $(bodyDom + ">div[lay-id]").attr("lay-id");
        var title = [];
        var $href = $(subMenuDom).find('[href="#/' + hash + '"]');
        if ($href.length > 0)
          title.push($href.text().replace(/(^\s*)|(\s*$)/g, ""));
        while (true) {
          $href = $href.parent("dd").parent("dl").prev("a");
          if ($href.length === 0) break;
          title.unshift($href.text().replace(/(^\s*)|(\s*$)/g, ""));
        }
        return title;
      },
      getBreadcrumbHtml: function (hash) {
        var breadcrumb = menu.getBreadcrumb(hash);
        var htmlStr =
          hash === plusRouter.index
            ? ""
            : '<a href="#/' + plusRouter.index + '">🖥️ 工作台</a>';
        for (var i = 0; i < breadcrumb.length - 1; i++) {
          if (htmlStr) htmlStr += '<span lay-separator="">/</span>';
          htmlStr += "<a><cite>" + breadcrumb[i] + "</cite></a>";
        }
        return htmlStr;
      },
      loadHome: function (data) {
        var url = location.hash;
        var cacheTabs = plus.getTempData("menuTabs");
        var data = plusTools.searchMenus(data.url, "mine");
        menu.reg([data]);
        var info = plusRouter.routerInfo(data.url);
        plusRouter.index = menu.getHashPath(info);
        menu.changeView({
          info: $.extend(info, {
            name: data.name,
            iframe: data.iframe,
            noChange: true,
          }),
          first: true,
          data: data,
        });
        if (config.pageTabs) {
          if (data.loadSetting !== false && config.cacheTab && cacheTabs) {
            for (var i = 0; i < cacheTabs.length; i++)
              menu.changeView({
                info: $.extend(cacheTabs[i], { noChange: true }),
                data: cacheTabs[i]
              });
          }
        } else {
          menu.activeMenu(data.url);
        }
        plusRouter.init({ index: data.url, notFound: config.routerNotFound });
      },
      addTab: function (param) {
        menu.reg([param]);
        plusRouter.go(param.url);
      },
      delTab: function (hash) {
        element.tabDelete(tabFilter, menu.getHashPath(hash));
      },
      pushTab: function () {
        if (config.pageTabs && $(tabDom).length === 0) {
          var html = [
            '<div class="layui-tab" lay-allowClose="true" lay-filter="',
            tabFilter,
            '" router-autoRefresh="',
            config.autoRefresh == true,
            '">',
            '   <ul class="layui-tab-title"></ul><div class="layui-tab-content"></div>',
            "</div>",
            '<div class="plus-admin-tabs-btn refresh" plus-tools="refresh" title="刷新">⭕</div>',
            '<div class="plus-admin-tabs-btn left" plus-tools="leftPage">⏮️</div>',
            '<div class="plus-admin-tabs-btn right" plus-tools="rightPage">⏭️</div>',
            '<div class="plus-admin-tabs-btn down">🔽',
            '   <ul class="layui-nav" lay-filter="plus-admin-pagetabs-nav">',
            '      <li class="layui-nav-item" lay-unselect>',
            '         <dl class="layui-nav-child layui-anim-fadein">',
            '            <dd plus-tools="closeThisTabs" lay-unselect><a>⛔️ 关闭当前标签</a></dd>',
            '            <dd plus-tools="closeOtherTabs" lay-unselect><a>🔶 关闭其它标签</a></dd>',
            '            <dd plus-tools="closeAllTabs" lay-unselect><a>❌ 关闭全部标签</a></dd>',
            "         </dl>",
            "      </li>",
            "   </ul>",
            "</div>",
          ].join("");
          $(bodyDom).html(html);
          element.render("nav", "plus-admin-pagetabs-nav");
        }
      },
      pushRight: function () {
        if (config.pageTabs) {
          $(tabDom + ">.layui-tab-title")
            .off("contextmenu.tab")
            .on("contextmenu.tab", "li", function (e) {
              var layId = $(this).attr("lay-id");
              if (layId !== plusRouter.index) {
                contextMenu.show(
                  [
                    {
                      icon: "⛔️",
                      name: "关闭当前",
                      click: function () {
                        plus.closeThisTabs(layId);
                      },
                    },
                    {
                      icon: "🔶",
                      name: "关闭其他",
                      click: function () {
                        plus.closeOtherTabs(layId);
                      },
                    },
                    {
                      icon: "❌",
                      name: "关闭全部",
                      click: function () {
                        plus.closeAllTabs();
                      },
                    },
                  ],
                  $(this).offset().left + ($(this).outerWidth() - 88) / 2,
                  $(this).offset().top + $(this).height() + 5
                );
              }
              return false;
            });
        }
      },
    };
    menu.init();
    exports("menu", menu);
  }
);
